package a1_p04_jw_kw.graph;

import java.util.ArrayList;
import java.util.List;

import a1_p04_jw_kw.struct.GraphSetup;
import a1_p04_jw_kw.struct.GraphTransition;
import a1_p04_jw_kw.struct.Node;

public class GraphParser {
	GraphIO graphIO;
	
	//terminal
	private final static String DIRECTED = "#gerichtet";
	private final static String UNDIRECTED = "#ungerichtet";
	private final static String ATTRIBUTED = "#attributiert";
	private final static String WEIGHTED = "#gewichtet";
	private final static String ATTRIBUTED_WEIGHTED = "#attributiert,gewichtet";
	
	//graph setup
	private Boolean attributed = false;
	private Boolean weighted = false;
	private Boolean directed = false;
	private Boolean undirected = false;
	private ArrayList<GraphTransition> transitions = new ArrayList<GraphTransition>();
	
	//known Vertexes
	List<Node> vertixes = new ArrayList<Node>();
	
	public GraphParser(String file) {
		this.graphIO = new GraphIO();
		this.graphIO.initializeInputStream(file);
		
		parse();
		
		this.graphIO.closeInputStream();
	}
	
	private void parse() {
		String line = this.graphIO.getNextLine();
		
		if (directedUndirected(line)) {
			
		}
		
		line = this.graphIO.getNextLine();

		if (line.startsWith("#")) {
			attributedWeighted(line);
			line = this.graphIO.getNextLine();
		} 
			
			
		while (transition(line)) {
			
			line = this.graphIO.getNextLine();	
		}
	}
	
	private boolean directedUndirected(String line) {
		if (line.equals(DIRECTED)) {
			this.directed = true;
			
			return true;
			
		} else if (line.equals(UNDIRECTED)) {
			this.undirected = true;
			
			return true;
		} else {
			System.out.println("wrong grammar dude");
			
			return false;
		}
		
	}
	
	private boolean transition(String line) {
		if (line == null) {
			
			return false;
		} else {
			String[] attributes = sliceStringByComma(line);
//			System.out.println(attributes[0] + " " + attributes[1]);
			
			addTransition(attributes);
			return true;
		}
		
	}
	
	private boolean attributedWeighted(String line) {
		if (line.equals(ATTRIBUTED)) {
			this.attributed = true;
			
			return true;
		} else if (line.equals(WEIGHTED)) {
			this.weighted = true;
			return true;
			
		} else if (line.equals(ATTRIBUTED_WEIGHTED)) {
			this.attributed = true;
			this.weighted = true;
			
			return true;
		} else {
			
			return false;
		}
	}
	
	public GraphSetup getGraphSetup() {
		GraphSetup gs = new GraphSetup(directed, undirected, attributed, weighted, transitions);
		
		return gs;
	}
	
	private String[] sliceStringByComma(String string) {
		return string.split(",");
		
	}
	
	private void addTransition(String[] attributes) {
		switch(attributes.length) {
		case 2: this.transitions.add(new GraphTransition(getNode(attributes[0]),getNode(attributes[1])));
				break;
		case 3: this.transitions.add(new GraphTransition(getNode(attributes[0]),getNode(attributes[1]),attributes[2]));
				break;		
		case 4: this.transitions.add(new GraphTransition(getNode(attributes[0]),attributes[1],getNode(attributes[2]),attributes[3]));
				break;
		case 5: this.transitions.add(new GraphTransition(getNode(attributes[0]),attributes[1],getNode(attributes[2]),attributes[3],attributes[4]));
				break;
		default: System.out.println("falsche laenge");
		
		}
	}
	
	public Node getNode(String name) {
		for (Node node : vertixes) {
			if (node.name.equals(name)) return node;
			
		} 
		Node newNode = new Node(name);
		vertixes.add(newNode);
		
		return newNode;
	}
}
